package com.test.work.scoreagg.service.db1.impl;

import com.alibaba.fastjson2.JSONObject;
import com.test.work.scoreagg.pojo.db1.EvalCompanyResult;
import com.test.work.scoreagg.pojo.db1.EvalCompanyResultDto;
import com.test.work.scoreagg.pojo.db1.MongoObjectModel;
import com.test.work.scoreagg.service.db1.EvalCompanyResultService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.*;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.stereotype.Service;


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import cn.hutool.core.util.ObjectUtil;
import org.springframework.util.CollectionUtils;

@Service
@Slf4j
public class EvalCompanyResultServiceImpl implements EvalCompanyResultService {


    @Autowired
    MongoTemplate mongoTemplate;


    @Override
    public List<EvalCompanyResult> getEvalCompanyResultList() {
        return mongoTemplate.findAll(EvalCompanyResult.class);
    }

    /**
     *
     * 1) 设定Criteria 2)创建Query对象 3)	设置查询条件 4) 执行查询
     * */

    @Override
    public List<MongoObjectModel> getMongoObjectData(List<String> collectBatches, List<String> quotaGroupNameList, String objectCode, String countyCode, List<String> countyCodeList) {
        //比如筛选city_code字段等于10000010的文档
        Criteria criteria = Criteria.where("city_code").is("10000010")
                .and("collect_batch").in(collectBatches)
                .and("eval_status").is("DON");

        //筛选区县条件
        if (CollUtil.isNotEmpty(countyCodeList)) {
            criteria.andOperator(
                    new Criteria().orOperator(
                            Criteria.where("county_code").in(countyCodeList),
                            Criteria.where("county_code").is(null)
                    )
            );
        }
        if (ObjectUtil.isNotEmpty(countyCode)) {
            criteria.and("county_code").is(countyCode);
        }

        //一级分组名称
        if (CollUtil.isNotEmpty(quotaGroupNameList)) {
            criteria.and("L1_quota_group_name").in(quotaGroupNameList);
        }
        //筛选具体的企业
        if (ObjectUtil.isNotEmpty(objectCode)) {
            criteria.and("object_code").is(objectCode);
        }
        // Match stage
        MatchOperation matchOperation = Aggregation.match(criteria);

        // Group stage 将集合中的文档分组，用于统计集合
        GroupOperation groupOperation = Aggregation.group(
                "county_code", "county_name", "object_code", "object_name", "object_type", "L1_quota_group_code", "L1_quota_group_name"
        ).sum("quota_value").as("quotaGroupValue");

        // Project stage 修改输入文档的结构
        ProjectionOperation projectionOperation = Aggregation.project()
                .and("$_id.county_code").as("countyCode")
                .and("$_id.county_name").as("countyName")
                .and("$_id.object_code").as("objectCode")
                .and("$_id.object_name").as("objectName")
                .and("$_id.object_type").as("objectType")
                .and("$_id.L1_quota_group_code").as("quotaGroupCode")
                .and("$_id.L1_quota_group_name").as("quotaGroupName")
                .and("quotaGroupValue").as("quotaGroupValue")
                .andExclude("_id");

        // Create aggregation pipeline
        Aggregation aggregation = Aggregation.newAggregation(
                matchOperation,
                groupOperation,
                projectionOperation
        );
        return mongoTemplate.aggregate(aggregation,"eval_company_result", MongoObjectModel.class).getMappedResults();

    }

    @Override
    public List<EvalCompanyResultDto> getEvalCompResuList(String objectCode) {

        /*
        Criteria criteria = Criteria.where("object_code").is(objectCode);

        // Match stage
        MatchOperation matchOperation = Aggregation.match(criteria);

        SortOperation sortOperation = Aggregation.sort(Sort.Direction.DESC,"create_time");


        // Project stage 修改输入文档的结构
        ProjectionOperation projectionOperation = Aggregation.project()
                .and("$_id.object_name").as("objectName")
                .and("$_id.object_code").as("objectCode")
                .and("$_id.quota_name").as("quotaName")
                .and("$_id.quota_operate_running").as("quotaOperateRunning")
                .and("$_id.quota_value").as("quotaValue")
                .and("$_id.create_time").as("createTime")
                //.and("popSum").as("popSumValue")
                .andExclude("_id");


        Aggregation aggregation = Aggregation.newAggregation(
                matchOperation,
                sortOperation,
                projectionOperation
        );

        List<EvalCompanyResult> evalCompanyResult = mongoTemplate.aggregate(aggregation, "eval_company_result", EvalCompanyResult.class).getMappedResults();
        log.info("evalCompanyResult："+ JSONObject.toJSONString(evalCompanyResult));*/


        //从第5行开始，查询3条数据返回
        Query query = new Query(Criteria.where("object_code").is(objectCode))
                .with(Sort.by("create_time"));
                //.limit(3).skip(5);
        List<Map> evalCompanyResult = mongoTemplate.find(query, Map.class, "eval_company_result");
        List<EvalCompanyResultDto> resultDtoList = new ArrayList<>();
        if (!CollectionUtils.isEmpty(evalCompanyResult)) {
            for (int i = 0; i < evalCompanyResult.size(); i++) {
                Map map =  evalCompanyResult.get(i);
                EvalCompanyResultDto cur = new EvalCompanyResultDto();
                cur.setId(ObjectUtil.isEmpty(map.get("_id"))?"":map.get("_id").toString());
                cur.setObjectName(ObjectUtil.isEmpty(map.get("object_name"))?"":map.get("object_name").toString());
                cur.setQuotaName(ObjectUtil.isEmpty(map.get("quota_name"))?"":map.get("quota_name").toString());
                cur.setQuotaOperateRunning(ObjectUtil.isEmpty(map.get("quota_operate_running"))?"":map.get("quota_operate_running").toString());
                cur.setQuotaoValue(ObjectUtil.isEmpty(map.get("quota_value"))?"":map.get("quota_value").toString());
                resultDtoList.add(cur);
            }
        }

        System.out.println(resultDtoList);
        return resultDtoList;
    }
}
